<?php

/**
 * Member form.
 *
 * @package    docplus.co.za
 * @subpackage form
 * @author     Fox Matuku
 * @version    SVN: $Id: sfDoctrineFormTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class MemberForm extends BaseMemberForm
{
    private $requiredFields = array('email');

    public function configure()
    {
        unset(
            $this['created_at'], $this['updated_at']
        );

        // grab the gender generated options
        $genderOptions = $this->widgetSchema['gender']->getOptions("choices");

        $options = $this->getOptions();

        $this->widgetSchema['gender']->setOption("choices", array_merge(array("" => "Please select a gender"), $genderOptions["choices"]));
        $this->widgetSchema["gender"]->setAttribute("class", "select-box-small");

        $this->widgetSchema['first_name'] = !empty($options['is_step_two']) ? new sfWidgetFormInputHidden() : new sfWidgetFormInputText();
        $this->widgetSchema['last_name'] = !empty($options['is_step_two']) ? new sfWidgetFormInputHidden() : new sfWidgetFormInputText();
        $this->widgetSchema['profile_name'] = !empty($options['is_step_two']) ? new sfWidgetFormInputHidden() : new sfWidgetFormInputText();
        $this->widgetSchema['gender'] = !empty($options['is_step_two']) ? new sfWidgetFormInputHidden() : $this->widgetSchema['gender'];
        $this->widgetSchema['language_id'] = new sfWidgetFormInputHidden();
        $this->widgetSchema['email'] = !empty($options['is_step_one']) ? new sfWidgetFormInputHidden() : new sfWidgetFormInputText(array(), array("title" => "Email", "autocomplete" => "off"));
        $this->widgetSchema['password'] = !empty($options['is_step_one']) ? new sfWidgetFormInputHidden() : new sfWidgetFormInputPassword(array(), array("title" => "Password", "autocomplete" => "off"));
        $this->widgetSchema['terms'] = !empty($options['is_step_one']) ? new sfWidgetFormInputHidden() : new sfWidgetFormInputCheckbox(array(), array('value' => "1", "class" => "checkbox"));
        $this->widgetSchema['password_confirm'] = new sfWidgetFormInputPassword();
        $this->widgetSchema['password_confirm']->setAttributes(array())->setLabel("Confirm password");
        $this->widgetSchema['terms']->setLabel("I accept DocPlus' <a href=\"/terms-of-use\" target=\"_blank\">Terms of Use</a>");
        $this->widgetSchema['gallery_item_id'] = new sfWidgetFormInputHidden(array(), array('value' => !empty($options['gallery_item_id']) ? $options['gallery_item_id'] : null));

        $this->validatorSchema['user_id'] = new sfValidatorString(array('required' => false));
        $this->validatorSchema['password'] = new sfValidatorString(array('max_length' => 128, 'required' => (bool) empty($options['is_step_one'])), array('required' => 'Your *password* is required.'));
        $this->validatorSchema['password_confirm'] = clone $this->validatorSchema['password'];
        $this->validatorSchema['gender'] = new sfValidatorString(array('max_length' => 255, 'required' => true), array('required' => 'Your *gender* is required.'));
        $this->validatorSchema['first_name'] = new sfValidatorString(array('max_length' => 255, 'required' => true), array('required' => 'Your *first name* is required.'));
        $this->validatorSchema['profile_name'] = new sfValidatorString(array('max_length' => 255, 'required' => true), array('required' => 'Your *profile name* is required.'));
        $this->validatorSchema['last_name'] = new sfValidatorString(array('max_length' => 255, 'required' => true), array('required' => 'Your *last name* is required.'));
        $this->validatorSchema['language_id'] = new sfValidatorString(array('required' => false));
        $this->validatorSchema['email'] = new sfValidatorEmail(array("required" => !empty($options['is_step_one'])), array("invalid" => "Your *email* is invalid.", "required" => "Your *email* is required email."));
        $this->validatorSchema['password_confirm']->setMessage('required', 'Your *confirm password* is required.');
        $this->validatorSchema['terms'] = new sfValidatorString(array("required" => (bool) empty($options['is_step_one'])), array("required" => "Please accept our *terms of use*."));
        $this->validatorSchema['gallery_item_id'] = new sfValidatorString(array('required' => false));

        $this->validatorSchema->setPostValidator(new sfValidatorAnd(array(
                new sfValidatorCallback(array('callback' => array($this, '_emailAlreadyExistsValidator'))),
                new sfValidatorDoctrineUnique(array('model' => 'Member', 'column' => array('profile_name')), array('invalid' => "Profile name is already taken"))
            )));
        $this->mergePostValidator(new sfValidatorSchemaCompare('password', sfValidatorSchemaCompare::EQUAL, 'password_confirm', array(), array('invalid' => 'Your *two passwords* must be equal.')));
    }

    public function _emailAlreadyExistsValidator($validator, $values, $arguments)
    {
        foreach ($this->requiredFields as $field)
        {
            try
            {
                $this->validatorSchema[$field]->clean($values[$field]);
            }
            catch (sfValidatorErrorSchema $e)
            {
                return $values;
            }
            catch (sfValidatorError $e)
            {
                return $values;
            }
        }

        // try to fetch the supplied email
        $gfUser = GfUserTable::getInstance()->findOneByEmail($values['email']);

        // check for the existence of a user with this email
        if (is_object($gfUser))
        {
            $this->validatorSchema['email']->setMessage('invalid', 'This email already exists.');
        }
        else
        {
            return $values;
        }

        // since we've reached here seems the supplied email exists already
        throw new sfValidatorErrorSchema($this->validatorSchema['email'], array('email' => new sfValidatorError($this->validatorSchema['email'], 'invalid')));
        return $values;
    }

    /**
     * Override the save method to save the merged user form.
     */
    public function save($con = null)
    {
        $this->updateUser();
        return parent::save($con);
    }

    /**
     * Updates the user merged form
     */
    protected function updateUser()
    {
        if (!is_null($user = $this->getUser()))
        {
            if (!$user->getId())
            {
                $user->setAlgorithm('md5');
                $user->setEmail($this->getValue("email"));
                $user->setPassword($this->getValue("password"));
            }
            $user->setFirstName($this->getValue("first_name"));
            $user->setLastName($this->getValue("last_name"));
            $user->setEmail($this->getValue("email"));
            $user->save();

            // set the default group
            $user->addGroupByName('Members');

            // set the default permission
            $user->addPermissionByName('Member');

            unset($this->values['password']);

            // set the user id
            $this->values['user_id'] = $user->get('id');
        }
    }

    /**
     * Returns the user object. If it does not exist return a new instance.
     *
     * @return sfGuardUser
     */
    protected function getUser()
    {
        if (!$this->getObject()->getUser())
        {
            return new GfUser();
        }

        return $this->getObject()->getUser();
    }

}
